package com.rsstuan.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;

import javax.cache.Cache;
import javax.cache.CacheFactory;
import javax.cache.CacheManager;


import com.google.appengine.api.memcache.jsr107cache.GCacheFactory;
import com.rsstuan.storage.data.TuanGouChannelData;
import com.rsstuan.storage.impl.JDOTuanGouChannelStorage;

public class ChannelService {
	
	private Logger LOG = Logger.getLogger(ChannelService.class.getName());
	private Cache cache;
	
	private Properties props = new Properties();
	
	private JDOTuanGouChannelStorage channelStorage = new JDOTuanGouChannelStorage();
	
	
	private static ChannelService instance = new ChannelService();
	
	public static ChannelService getInstance() {
		return instance;
	}
	
	public ChannelService() {
		try {
			props.put(GCacheFactory.EXPIRATION_DELTA, 60*60*24);
			CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
	        cache = cacheFactory.createCache(Collections.emptyMap());
		}
		catch (Exception e) {
			
		}
	}
	
	public String getChannelName(Long channelId) {
	    TuanGouChannelData channel = getChannel(channelId);
	    if (channel != null)
	        return channel.getTitle();
	    else 
	        return "";
	}
	
	public TuanGouChannelData getChannel(Long channelId) {
		TuanGouChannelData channel = loadFromCache(channelId);
		if (channel != null) {
			return channel;
		} else {
			 channel = channelStorage.getChannel(channelId);
			if (channel != null) {
				putIntoCache(channel);
				return (TuanGouChannelData) channel.clone();
			}
			return channel;
		}
	}
	public List<TuanGouChannelData> getAllChannels() {
		if (cache.get("allChannels") != null) {
			List<TuanGouChannelData> channels = new ArrayList<TuanGouChannelData>();
			String channelSeq = (String)cache.get("allChannels");
			String[] idStrs = channelSeq.split(",");
			for (String idStr : idStrs) {
				Long channelId = Long.parseLong(idStr);
				TuanGouChannelData channel = getChannel(channelId);
				channels.add(channel);
			}
			return channels;
		} else {
			List<TuanGouChannelData> channels = channelStorage.getAllChannels();
			StringBuilder sb = new StringBuilder();
			for (TuanGouChannelData channel : channels) {
				sb.append(channel.getId()+",");
				putIntoCache(channel);
			}
			cache.put("allChannels", sb.substring(0, sb.length()-1));
			return channels;
		}
	}

	public Map<Long, TuanGouChannelData> getAllChannelsMap() {
		
		List<TuanGouChannelData> channels = getAllChannels();
		Map<Long, TuanGouChannelData> map = new HashMap<Long, TuanGouChannelData>();
		if (channels != null) {
			for (TuanGouChannelData channel : channels) {
				if (channel != null)
					map.put(channel.getId(), channel);
			}
		}
		return map;	
	}
	
	private TuanGouChannelData loadFromCache(Long channelId) {
		String idStr = channelId.toString();
		if (cache.get(idStr +"_id") != null) {
			TuanGouChannelData channel = new TuanGouChannelData();
			channel.setId(channelId);
			channel.setSiteId((Long)cache.get(idStr+"_siteId"));
			channel.setTitle((String)cache.get(idStr+"_title"));
			channel.setLink((String)cache.get(idStr+"_link"));
			channel.setCity((String)cache.get(idStr+"_city"));	
			return channel;
		} 
		else 
			return null;
	}
	
	private void putIntoCache(TuanGouChannelData channel) {
		String idStr = channel.getId().toString();
		cache.put(idStr+"_id", channel.getId());
		cache.put(idStr+"_siteId", channel.getSiteId());
		cache.put(idStr+"_title", (Object)channel.getTitle());
		cache.put(idStr+"_link", channel.getLink());
		cache.put(idStr+"_city", channel.getCity());
	}
	
	public Long getLastCrawlChannelId() {
		if (cache.get("lastCrawlChannelId") == null) {
			return -1L;
		}
		else {
		
			return (Long)cache.get("lastCrawlChannelId");
		}
	}
	public void setLastCrawlChannelId(Long channelId) {
		cache.put("lastCrawlChannelId", channelId);
	}
	
	public void clearCache() {
		cache.clear();
	}

}
